/**   
* @Title: TxAdvice.java
* @Package com.jbeer.framework.db.tx
* @author Bieber
* @date 2014年5月27日 上午11:34:29
* @version V1.0   
*/

package com.jbeer.framework.db.tx;

import com.jbeer.framework.annotation.Tx;
import com.jbeer.framework.aop.Advice;
import com.jbeer.framework.bean.proxy.InvokeHandler;
import com.jbeer.framework.db.JBeerDBContext;

/**
* <p>类功能说明:事务增强类</p>
* <p>类修改者	    修改日期</p>
* <p>修改说明</p>
* <p>Title: TxAdvice.java</p>
* @author Bieber <a mailto="bieber.jbeer@hotmail.com">bieber.jbeer@hotmail.com</a>
* @date 2014年5月27日 上午11:34:29
* @version V1.0
*/

public class TxAdvice extends Advice {

    /* (non-Javadoc)
     * @see com.jbeer.framework.aop.Advice#before(com.jbeer.framework.bean.proxy.InvokeHandler)
     */
    @Override
    public void before(InvokeHandler handler) throws Throwable {
        //开启事务
        Tx tx = handler.getInvokeMethod().getAnnotation(Tx.class);
        if (tx != null) {
            TranscationManager.initializeTranscationManager();
            TranscationDefinition definition = new TranscationDefinition(handler.getInvokeMethod()
                .getName());
            definition.setIsolation(tx.isolation());
            definition.setPropagation(tx.propagation());
            definition.setReadonly(tx.readonly());
            definition.setRollbackFor(tx.rollbackFor());
            TranscationManager.registTranscation(definition, JBeerDBContext.datasource);
        }
    }

    /* (non-Javadoc)
     * @see com.jbeer.framework.aop.Advice#after(com.jbeer.framework.bean.proxy.InvokeHandler, java.lang.Object)
     */
    @Override
    public void after(InvokeHandler handler, Object ret) throws Throwable {
        //提交事务
        Tx tx = handler.getInvokeMethod().getAnnotation(Tx.class);
        if (tx != null) {
            TranscationStatus status = TranscationManager
                .getCurrentTranscation(JBeerDBContext.datasource);
            if (status != null) {
                status.setCompleted(true);
            }
            TranscationManager.commit(JBeerDBContext.datasource);
        }
    }

    /* (non-Javadoc)
     * @see com.jbeer.framework.aop.Advice#exception(com.jbeer.framework.bean.proxy.InvokeHandler, java.lang.Throwable)
     */
    @Override
    public void exception(InvokeHandler handler, Throwable e) throws Throwable {
        //回滚事务
        TranscationStatus status = TranscationManager
            .getCurrentTranscation(JBeerDBContext.datasource);
        Tx tx = handler.getInvokeMethod().getAnnotation(Tx.class);
        if (tx != null) {
            Class<? extends Throwable>[] ts = tx.rollbackFor();
            if (ts != null && ts.length <= 0) {
                for (Class<? extends Throwable> t : ts) {
                    if (t.isAssignableFrom(e.getClass())) {
                        if (status != null) {
                            status.setRollBack(true);
                        }
                        break;
                    }
                }
            }
            TranscationManager.commit(JBeerDBContext.datasource);
        }
    }

}
